package com.mornd.controller.crud;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mornd.annotation.LogStar;
import com.mornd.consts.RoleConst;
import com.mornd.consts.ShiroConst;
import com.mornd.consts.UserConst;
import com.mornd.entity.Menu;
import com.mornd.entity.Role;
import com.mornd.entity.TreeNode;
import com.mornd.result.AjaxResult;
import com.mornd.result.DataGridView;
import com.mornd.service.MenuService;
import com.mornd.service.RoleService;
import com.mornd.vo.RoleVo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author mornd
 * @date 2021/1/6 - 20:46
 * 操作角色的控制器层
 */
@RestController
@RequestMapping("/role")
@RequiresPermissions({"m:role"})
public class RoleController {
    @Resource
    private RoleService roleService;
    @Resource
    private MenuService menuService;

    /**
     * 查询角色集合
     * @return
     */
    @PostMapping("/getRole")
    public List<Role> getRoleList(){
        return roleService.list();
    }

    /**
     * 根据条件查询角色集合
     * @param roleVo
     * @return
     */
    @LogStar("查询角色")
    @GetMapping("/findRole")
    public DataGridView<Role> findRole(RoleVo roleVo){
        IPage<Role> list = roleService.findList(roleVo);
        return new DataGridView<Role>(list.getTotal(),list.getRecords());
    }

    /**
     * 保存角色
     * @param role 页面传来角色对象
     * @param mids 菜单id
     * @return
     */
    @LogStar("保存角色")
    @PostMapping("/save")
    public Map saveRole(Role role,@RequestParam("mids") String mids){
        if(ObjectUtils.isEmpty(role)){
            return AjaxResult.failure("提交数据为空");
        }
        if(ObjectUtils.isEmpty(role.getName()) || ObjectUtils.isEmpty(role.getName())){
            return AjaxResult.failure("请输入必填项");
        }
        //给角色编码加R_前缀
        StringBuffer buffer = new StringBuffer(RoleConst.ROLE_PREFIX);
        buffer.append(role.getCode());
        role.setCode(buffer.toString().toUpperCase());
        //判断角色信息是否已经存在
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("name",role.getName());
        if(!ObjectUtils.isEmpty(roleService.getOne(wrapper))){
            return AjaxResult.failure("该角色名称已存在");
        }
        wrapper = new QueryWrapper<>();
        wrapper.eq("code",role.getCode());
        if(!ObjectUtils.isEmpty(roleService.getOne(wrapper))){
            return AjaxResult.failure("该角色编码已存在");
        }
        //保存角色
        if (roleService.save(role)) {
            if(!ObjectUtils.isEmpty(mids)){
                //将字符串分割为数组
                List<Integer> list = new ArrayList<Integer>();
                String[] splitByIds = mids.split(",");
                for (String mid : splitByIds) {
                    list.add(Integer.valueOf(mid));
                }
                try {
                    //保存角色对应的菜单
                    roleService.addMenuByRoleId(role.getId(),list);
                }catch (Exception e){
                    e.printStackTrace();
                    return AjaxResult.failure("添加菜单异常");
                }
            }
            return AjaxResult.success("保存角色成功");
        }
        return AjaxResult.failure("保存角色失败！");
    }

    /**
     * 编辑用户
     * @param role 角色对象
     * @param mids 菜单id字符串
     * @return
     */
    @LogStar("编辑角色")
    @PostMapping("/edit")
    public Map editRole(Role role,@RequestParam("mids") String mids){
        if(ObjectUtils.isEmpty(role)){
            return AjaxResult.failure("提交数据为空");
        }
        if(ObjectUtils.isEmpty(role.getName()) || ObjectUtils.isEmpty(role.getName())){
            return AjaxResult.failure("请输入必填项");
        }
        //转大写
        role.setCode(role.getCode().toUpperCase());
        if(!role.getCode().startsWith(RoleConst.ROLE_PREFIX)){
            //给角色编码加R_前缀
            StringBuffer buffer = new StringBuffer(RoleConst.ROLE_PREFIX);
            buffer.append(role.getCode());
            role.setCode(buffer.toString());
        }
        //判断角色信息是否已经存在
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("name",role.getName());
        Role selectRole = roleService.getOne(wrapper);
        if(!ObjectUtils.isEmpty(selectRole) && !role.getId().equals(selectRole.getId())){
            return AjaxResult.failure("该角色名称已存在");
        }
        wrapper = new QueryWrapper<>();
        wrapper.eq("code",role.getCode());
        selectRole = roleService.getOne(wrapper);
        if(!ObjectUtils.isEmpty(selectRole) && !role.getId().equals(selectRole.getId())){
            return AjaxResult.failure("该角色编码已存在");
        }
        //清空该角色对应的所有菜单
        try {
            roleService.deleteRoleAndMenuRelation(role.getId());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.failure("删除中间表时发生异常，请重试！");
        }
        //修改所属菜单
        if(!ObjectUtils.isEmpty(mids)){
            //将字符串分割为数组
            List<Integer> list = new ArrayList<Integer>();
            String[] splitByIds = mids.split(",");
            for (String mid : splitByIds) {
                list.add(Integer.valueOf(mid));
            }
            try {
                //保存角色对应的菜单
                roleService.addMenuByRoleId(role.getId(),list);
            }catch (Exception e){
                e.printStackTrace();
                return AjaxResult.failure("添加菜单异常");
            }
        }
        role.setGmtModified(new Date());
        //编辑用户
        if(roleService.updateById(role)){
            return AjaxResult.success("角色修改成功");
        }
        return AjaxResult.failure("角色修改失败，请重试！");
    }

    /**
     * 角色添加或编辑时，加载角色id对应的菜单tree
     * @return
     */
    @PostMapping("/initRoleMenuTree/{roleId}")
    public DataGridView initRoleMenuTree(@PathVariable("roleId") Integer id){
        List<Menu> menuList = menuService.list();
        //是否是编辑角色
        boolean isEdit = !ObjectUtils.isEmpty(id) && id != 0;
        List<Integer> menuListById = null;
        if(isEdit){
            //查询对应的菜单id集合
            menuListById = roleService.findMenuByRoleId(id);
        }
        //定义页面所需的TreeNode类型集合
        List<TreeNode> treeNodes = new ArrayList<TreeNode>();
        for (Menu menu : menuList) {
            //是否选中 0未选中 1选中
            String checkArr = "0";
            if(isEdit && !ObjectUtils.isEmpty(menuListById)){
                for (Integer MenuId : menuListById) {
                    if(menu.getId() == MenuId){
                        //选中状态
                        checkArr = "1";
                        break;
                    }
                }
            }
            treeNodes.add(new TreeNode(menu.getId(),menu.getPid(),
                    menu.getTitle(),menu.getSpread() == 1,checkArr));
        }
        return new DataGridView<TreeNode>((long) treeNodes.size(),treeNodes);
    }

    /**
     * 查询该角色下是否有对应的用户
     * @param roleId
     * @return
     */
    @PostMapping("/checkIfExistUser/{roleId}")
    public Map checkIfExistUser(@PathVariable("roleId") Integer roleId){
        if(ObjectUtils.isEmpty(roleId)){
            return AjaxResult.failure("提交数据为空");
        }
        if(UserConst.SA_ID == roleId){
            return AjaxResult.isExists(true,"超级管理员，不可删除！");
        }
        if(roleService.checkRoleIfExistByUser(roleId) > 0){
            return AjaxResult.isExists(true,"该角色下已有用户，不可删除！");
        }
        return AjaxResult.isExists(false,null);
    }

    /**
     * 根据角色id删除角色
     * @param roleId
     * @return
     */
    @LogStar("删除角色")
    @PostMapping("/delete/{id}")
    public Map deleteRole(@PathVariable("id") Integer roleId){
        //执行删除角色操作
        if(roleService.removeById(roleId)){
            return AjaxResult.success("角色删除成功！");
        }
        return AjaxResult.failure("角色删除失败！");
    }
}
